import one from './img/one.jpg';
import two from './img/two.jpg';
const compiler = require('vue-template-compiler')
const _ = require('lodash');

const compilerTem = compiler.compile('<div>111</div>');

( (txt = 'hello webpack another chunk') => {
  const ele = document.createElement('h1');
  const main = document.createElement('div');
  const img1 = document.createElement('img');
  const img2 = document.createElement('img');
  const input = document.createElement('input')
  ele.innerText = txt;
  main.id = 'container';
  main.innerText = 'snabbdom';
  img1.src = one;
  img2.src = two;
  document.body.appendChild(input)
  document.body.appendChild(ele)
  document.body.appendChild(main)
  document.body.appendChild(img1)
  document.body.appendChild(img2)
  

  // 初始数据
  const data = {
    name: 'jupiter',
    age: '27',
    location: {
      address: 'jms'
    },
    telephone:[1,2]
  }
 
  // 更新视图
  function updateView() {
    console.log(`视图更新`);
  }
  
  // 重新定义数组原型
  const arrayPrototype = Array.prototype;
  const observerArray = Object.create(arrayPrototype);
  // 重新定义数据hack
  ['push', 'pop', 'shift', 'unshift', 'splice', 'slice', 'sort', 'reverse'].forEach( methodName =>{
    observerArray[methodName] = function(){
      arrayPrototype[methodName].call(this, ...arguments)
      updateView();
    };
  })



  // 重新定义属性 监听
  function defineReactive(target, key, value) {
    // 深度监听 可以直接对value 进行监听 也可以在 observer 函数递归
    observer(target[key])

    Object.defineProperty(target, key, {
      get () {
        return value
      },
      set(newVal) {
        newVal !== value && (value = newVal);
        // 对新值也需要深度监听 以防深层对象值修改
        observer(newVal)
        updateView()
      }
    })
  }

  // 监听对象属性
  function observer(target) {
    if(typeof target !== 'object' || target === null) {return  target}
    if(Array.isArray(target)){
      Reflect.setPrototypeOf(target, observerArray);
    }
    for (const key in target) {
      if (Object.hasOwnProperty.call(target, key)) {
        // 深度监听 可以采用递归形成监听
        // if(typeof target === 'object') {
        //   observer(target[key])
        // }
        defineReactive(target, key, target[key])
      }
    }
  }

  observer(data)

  // data.age = 22;
  // data.name = 'Jerry';
  data.location.address = 'bj';
  data.telephone.push(4);
})()